home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 201-225 / 214 / mandelvroom / src / recolor.c < prev    next >
C/C++ Source or Header  |  1995-03-13  |  26KB  |  870 lines

  1. /*
  2.  * MandelVroom 2.0
  3.  *
  4.  * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
  5.  *
  6.  * All rights reserved.
  7.  *
  8.  * Permission is hereby granted to distribute this program's source
  9.  * executable, and documentation for non-comercial purposes, so long as the
  10.  * copyright notices are not removed from the sources, executable or
  11.  * documentation.  This program may not be distributed for a profit without
  12.  * the express written consent of the author Kevin L. Clague.
  13.  *
  14.  * This program is not in the public domain.
  15.  *
  16.  * Fred Fish is expressly granted permission to distribute this program's
  17.  * source and executable as part of the "Fred Fish freely redistributable
  18.  * Amiga software library."
  19.  *
  20.  * Permission is expressly granted for this program and it's source to be
  21.  * distributed as part of the Amicus Amiga software disks, and the
  22.  * First Amiga User Group's Hot Mix disks.
  23.  *
  24.  * contents: this file contains functions to redraw (or repaint) Mandelbrot
  25.  * and Julia projects.  There are special high-performance functions to
  26.  * recolor 4 and 5 bit plane pictures (in assembly).  There is also a
  27.  * function that can spawn off a child task to redraw the picture (for the
  28.  * other number of bit planes 1,2,3 and 6)
  29.  */
  30.  
  31. #include "mandp.h"
  32.  
  33. extern LONG pSigMask;
  34.  
  35. /*
  36.  * ReColor a picture into a window
  37.  */
  38. ReColor( Pict )
  39.   register struct Picture *Pict;
  40. {
  41.   /* This set of variables should not be rearranged or moved.
  42.      There is Assembly language used in this routine, to increase
  43.      performance.  The assembly code depends on these variables
  44.      being located on Manx's stack.  Obviously it is not too portable
  45.      or maintainable, but it is faster.
  46.    */
  47.   SHORT *CountPtr;
  48.   UBYTE *ColorPtr;
  49.  
  50.   register LONG CountX, CountY;
  51.  
  52.   /* These variables are O.K. to rearrange and add to. */
  53.  
  54.   register struct Window  *Window;
  55.   register LONG   dx,dy;
  56.  
  57.   LONG i, Depth;
  58.  
  59.   UBYTE *ColorSave;
  60.  
  61.   LONG   wx,wy,Sx;
  62.  
  63.   if ( Pict == NULL )
  64.     return;
  65.  
  66.   KillReColor( Pict );
  67.   FreeScrollTemp( Pict );
  68.   PauseChild(Pict);
  69.  
  70.   Window = Pict->Window;
  71.   CountPtr = Pict->Counts;
  72.   CountX = Pict->CountX;
  73.   CountY = Pict->CountY;
  74.  
  75.   Depth = screen->BitMap.Depth;
  76.  
  77.   if (CountPtr == NULL || Pict->Flags & NO_RAM_GENERATE ) {
  78.     DispErrMsg("No counts to recolor",0);
  79.     return;
  80.   }
  81.  
  82.   wx = CountX + Pict->LeftMarg + Pict->RightMarg;
  83.   wy = CountY + Pict->TopMarg  + Pict->BotMarg;
  84.  
  85.   dx = screen->Width  - wx;
  86.   dy = screen->Height - wy;
  87.  
  88.   if ( dx < 0 || dy < 0 ) {
  89.     DispErrMsg("Picture too big for screen.",0);
  90.     return;
  91.   }
  92.  
  93.   dx -= Window->LeftEdge;
  94.   dy -= Window->TopEdge;
  95.  
  96.   if ( dx < 0 || dy < 0 ) {
  97.     MoveWindow( Window, dx, dy );
  98.   }
  99.  
  100.   dx = wx - Window->Width;
  101.   dy = wy - Window->Height;
  102.  
  103.   if ( dx || dy ) {
  104.  
  105.     SizeWindow(Window, dx, dy );
  106.  
  107.     /* Spin till the window gets resized */
  108.     /* Gross eh? */
  109.  
  110.     i = 0;
  111.  
  112.     while (i++ < 10000 && Window->Width != wx && Window->Height != wy);
  113.  
  114.     if (i == 10000) {
  115.       DispErrMsg("can't resize the window");
  116.       return;
  117.     }
  118.  
  119.     BorderWindow(Window);
  120.   }
  121.  
  122.   if (Pict->CurLine+Pict->TopMarg < Pict->Window->Height-Pict->BotMarg-1) {
  123.  
  124.     SetAPen(  Pict->Window->RPort, NORMALPEN );
  125.     RectFill( Pict->Window->RPort, Pict->LeftMarg,
  126.               Pict->CurLine        + Pict->TopMarg,
  127.               Pict->Window->Width  - Pict->RightMarg - 1,
  128.               Pict->Window->Height - Pict->BotMarg   - 1);
  129.   }
  130.  
  131.   Pict->Flags &= ~LENS_DISPLAYED;
  132.  
  133.   MakeColorXlate( Pict );
  134.  
  135.   if ( Depth != 4 && Depth != 5) {
  136.     ReColorSlow( Pict );
  137.     return;
  138.   }
  139.  
  140.   /* try to get enough memory to recolor the picture fast. */
  141.  
  142.   ColorPtr = ColorSave =
  143.            (UBYTE *) safeAllocMem( CountX * CountY + 1, 0L);
  144.  
  145.   if (ColorPtr == (UBYTE *) NULL) {
  146.     ReColorSlow( Pict );
  147.     return;
  148.   }
  149.  
  150.   WindowToFront(Window);
  151.   ClearMenuStrip(Window);
  152.  
  153.   Delay(8);
  154.  
  155.   LockLayers( BackWind->WLayer->LayerInfo );
  156.  
  157.   /* We were able to allocate enough memory to translate the entire
  158.      picture from heights to pens.  The array of pens is used to
  159.      quickly recolor the screen using Recolor4 or Recolor5 */
  160.  
  161.   /* If you don't like the assembly, you can use this C instead */
  162.  
  163. #define SLOW1
  164. #ifdef SLOW1
  165.   for (Sx = CountX*CountY; Sx-- >= 0; )
  166.     *(ColorPtr++) = *(Pict->ClrXlate + *(CountPtr++));
  167.  
  168. #else
  169. #asm
  170. CountPtr  equ -4                     ; these define where your variables
  171. ColorBase equ -8                     ; are located on Manx's stack
  172.    move.w   d4,d1                    ; this is ugly, but CountX is in d4
  173.    muls.w   d5,d1                    ; and CountY is in d5
  174.    sub.l    #1,d1
  175.    move.l   CountPtr(a5),a0
  176.    move.l   _ColorXlate,a1
  177.    move.l   ColorBase(a5),a6
  178. ColorLoop
  179.    move.w   (a0)+,d0
  180.    move.b   (a1,d0.w),(a6)+
  181.    sub.l    #1,d1
  182.    bge      ColorLoop
  183. #endasm
  184. #endif
  185.  
  186.   if (Depth == 4) {
  187.     ReColor4( ColorSave, Pict);
  188.   } else
  189.   if (Depth == 5) {
  190.     ReColor5( ColorSave, Pict);
  191.   }
  192.   UnlockLayers( BackWind->WLayer->LayerInfo );
  193.   AwakenChild(Pict);
  194.  
  195.   SetMenuStrip(Window, Menu);
  196.  
  197.   FreeMem(ColorSave,CountX*CountY+1);
  198. } /* ReColor */
  199.  
  200. MakeColorXlate( Pict )
  201.   register struct Picture *Pict;
  202. {
  203.   register LONG i,j;
  204.  
  205.   /* So prepare the color translate table */
  206.   for (i = 0,j = 1023; i < NumContours; i++)
  207.     for (; j >= Pict->Heights[i] && j > 0; )
  208.      *(Pict->ClrXlate + j--) = Pict->Pens[i];
  209.   while (j >= 0) *(Pict->ClrXlate + j--) = 0;
  210. }
  211.  
  212. /*
  213.  * Assembly code to recolor 4 bit planes
  214.  */
  215. ReColor4(ColorSave, Pict)
  216.   UBYTE *ColorSave;
  217.   register struct Picture *Pict;
  218. {
  219.   /* This set of variables should not be rearranged or moved.
  220.      There is Assembly language used in this routine, to increase
  221.      performance.  The assembly code depends on these variables
  222.      being located on Manx's stack.  Obviously it is not too portable
  223.      or maintainable, but it is faster.
  224.    */
  225.   SHORT  Mask,Width;
  226.   LONG   Mod,CMod;
  227.   SHORT  LF,LP,RF,RP;
  228.   SHORT  i,j,k,l;
  229.   LONG   Sx,TL;
  230.   UBYTE  *ColorPtr;
  231.  
  232.   struct BitMap *BitMap;
  233.  
  234.   /* This can be messed with */
  235.  
  236.   SHORT  CountX, CountY;
  237.  
  238.   register struct Window  *Window;
  239.  
  240. #asm
  241. SaveReg  reg a0-a6/d0-d7
  242. Plane0   equ 8
  243. Plane1   equ Plane0+4
  244. Plane2   equ Plane0+8
  245. Plane3   equ Plane0+12
  246. Plane4   equ Plane0+16
  247. Plane5   equ Plane0+20
  248.  
  249. CountX    equ -50
  250. CountY    equ -48
  251. BitMap    equ -44
  252. ColorPtr  equ -40
  253. TL        equ -36
  254. Sx        equ -32
  255. l         equ -28
  256. k         equ -26
  257. j         equ -24
  258. i         equ -22
  259. RP        equ -20
  260. RF        equ -18
  261. LP        equ -16
  262. LF        equ -14
  263. CMod      equ -12
  264. Mod       equ -8
  265. Width     equ -4
  266. Mask      equ -2
  267. ColorSave equ 8
  268. #endasm
  269.  
  270.   Window = Pict->Window;
  271.   BitMap = Window->RPort->BitMap;
  272.   CountX = Pict->CountX;
  273.   CountY = Pict->CurLine;
  274.  
  275.   ColorPtr = ColorSave;
  276.   Sx = (screen->Width + 15) >> 4;
  277.   LP = Window->LeftEdge + Pict->LeftMarg;
  278.   LF = (LP + 15) & 0xfff0;
  279.   CMod = Pict->CountX - (LF-LP);
  280.   Mod = Sx - 1;
  281.   TL = Sx *  (Window->TopEdge + Pict->TopMarg) + (LP-1 >> 4);
  282.   Width = LF-LP;
  283.   Mask = 0xffff << Width;
  284.  
  285.   if ( Width > 0 ) {
  286.  
  287. #asm
  288.   movem.l SaveReg,-(sp)          ;Save all the gprs to the stack
  289.   move.l  a5,a1                  ;We need a5, so put MANX stack in a1
  290.   move.w  CountY(a5),i(a1)
  291.   move.l  BitMap(a1),a0
  292.   move.l  TL(a1),d0              ;Load Offset to Top,Left corner of screen
  293.   asl.l   #1,d0                  ; and make it a 'word' offset
  294.   move.l  Plane0(a0),a2          ;Get address of screens first bit plane
  295.   adda.l  d0,a2                  ; add in window top-left offset.
  296.   move.l  Plane1(a0),a3          ;Same for second bit plane.
  297.   adda.l  d0,a3
  298.   move.l  Plane2(a0),a4          ;Same for third bit plane.
  299.   adda.l  d0,a4
  300.   move.l  Plane3(a0),a5          ;Same for fourth bit plane.
  301.   adda.l  d0,a5
  302.   move.l  ColorPtr(a1),a0        ;Load up pointer to recolored data.
  303.   move.l  #1,d1                  ;/* for each row */
  304. ;                                for (i = CountY; i; i--) {
  305. Y0Loop4                            ; /* for each pixel in column */
  306.   move.w  Width(a1),d7           ;  for (k = Width; k; k--) {
  307.   eor.w   d2,d2                  ;  Clear all bits in the bit plane data regs.
  308.   eor.w   d3,d3
  309.   eor.w   d4,d4
  310.   eor.w   d5,d5
  311. B0Loop4
  312.   move.b  (a0)+,d0               ;    d0 = *(ColorPtr++);
  313.   asr.b   d1,d0                  ;    get low order bit from d0
  314.   addx.w  d2,d2                  ;    put it in bit plane 0 data
  315.   asr.b   d1,d0                  ;    same for bit plane 1
  316.   addx.w  d3,d3
  317.   asr.b   d1,d0                  ;    same for bit plane 2
  318.   addx.w  d4,d4
  319.   asr.b   d1,d0                  ;    same for bit plane 3
  320.   addx.w  d5,d5
  321.   sub.w   d1,d7                  ;    same for bit plane 5
  322.   bgt     B0Loop4                ;  } /* did each bit in bit plane word */
  323.   move.w  Mask(a1),d0            ;  Turn off all the new bits in planes
  324.   and.w   d0,(a2)
  325.   and.w   d0,(a3)
  326.   and.w   d0,(a4)
  327.   and.w   d0,(a5)
  328.   or.w    d2,(a2)+               ;  Set the new bits in the bit planes
  329.   or.w    d3,(a3)+
  330.   or.w    d4,(a4)+
  331.   or.w    d5,(a5)+
  332.   move.l  Mod(a1),d0             ;  Adjust plane pointers to start of next line
  333.   add.l   d0,d0
  334.   add.l   d0,a2
  335.   add.l   d0,a3
  336.   add.l   d0,a4
  337.   add.l   d0,a5
  338.   adda.l  CMod(a1),a0            ;  Adjust color pointer to start of next line
  339.   sub.w   d1,i(a1)               ;} /* did each row */
  340.   tst.w   i(a1)
  341.   bgt     Y0Loop4
  342.   movem.l (sp)+,SaveReg          ;better restore the registers
  343. #endasm
  344.   ;
  345.   }
  346.  
  347.   RP = LP + Pict->CountX & 0xfff0;
  348.   RF = RP - 16;
  349.   CMod = Pict->CountX - (RP-LF);
  350.   Mod = Sx - ((RP-LF) >> 4);
  351.   TL++;
  352.   Width = (RP-LF) >> 4;
  353.   ColorPtr = ColorSave + LF - LP;
  354.  
  355.   if (Width > 0 ) {
  356.  
  357. #asm
  358.   movem.l SaveReg,-(sp)          ;Save all the gprs to the stack
  359.   move.l  a5,a1                  ;We need a5, so put MANX stack in a1
  360.   move.w  CountY(a5),i(a1)          ;i = CountY;
  361.   move.l  BitMap(a1),a0
  362.   move.l  TL(a1),d0              ;Load Offset to Top,Left corner of screen
  363.   asl.l   #1,d0                  ; and make it a 'word' offset
  364.   move.l  Plane0(a0),a2          ;Get address of screens first bit plane
  365.   adda.l  d0,a2                  ; add in window top-left offset.
  366.   move.l  Plane1(a0),a3          ;Same for second bit plane.
  367.   adda.l  d0,a3
  368.   move.l  Plane2(a0),a4          ;Same for third bit plane.
  369.   adda.l  d0,a4
  370.   move.l  Plane3(a0),a5          ;Same for fourth bit plane.
  371.   adda.l  d0,a5
  372.   move.l  ColorPtr(a1),a0        ;Load up pointer to recolored data.
  373.   move.l  #1,d1                  ;/* for each row */
  374. ;                                for (i = CountY; i; i--) {
  375. YLoop4                            ; /* for each column */
  376.   move.w  Width(a1),j(a1)        ;  for (j = Width; j; j--) {
  377. XLoop4                               ; /* pack a word for each bit plane */
  378.   move.w  #16,d7                 ;    for (k = 16; k; k--) {
  379. BLoop4
  380.   move.b  (a0)+,d0               ;      d0 = *(ColorPtr++);
  381.   asr.b   d1,d0                  ;      get low order bit from d0
  382.   addx.w  d2,d2                  ;      put it in bit plane 0 data
  383.   asr.b   d1,d0                  ;      same for bit plane 1
  384.   addx.w  d3,d3
  385.   asr.b   d1,d0                  ;      same for bit plane 2
  386.   addx.w  d4,d4
  387.   asr.b   d1,d0                  ;      same for bit plane 3
  388.   addx.w  d5,d5
  389.   sub.w   d1,d7                  ;      same for bit plane 5
  390.   bgt     BLoop4                 ;    } /* did each bit in bit plane word */
  391.   move.w  d2,(a2)+               ;    Save the packed data in bit planes
  392.   move.w  d3,(a3)+
  393.   move.w  d4,(a4)+
  394.   move.w  d5,(a5)+
  395.   sub.w   d1,j(a1)               ;  } /* did each word in a row */
  396.   tst.w   j(a1)
  397.   bgt     XLoop4
  398.   move.l  Mod(a1),d0             ;  Adjust plane pointers to start of next line
  399.   add.l   d0,d0
  400.   add.l   d0,a2
  401.   add.l   d0,a3
  402.   add.l   d0,a4
  403.   add.l   d0,a5
  404.   adda.l  CMod(a1),a0            ;  Adjust color pointer to start of next line
  405.   sub.w   d1,i(a1)               ;} /* did each row */
  406.   tst.w   i(a1)
  407.   bgt     YLoop4
  408.   movem.l (sp)+,SaveReg          ;better restore the registers
  409. #endasm
  410.   ;
  411.   }
  412.  
  413.   TL += Width;
  414.   Width = LP + Pict->CountX - RP;
  415.   CMod = Pict->CountX - Width;
  416.   Mod = Sx - 1;
  417.   Mask = 0xffff >> Width;
  418.   ColorPtr = ColorSave + RP - LP;
  419.  
  420.   if ( Width > 0 ) {
  421.  
  422. #asm
  423.   movem.l SaveReg,-(sp)          ;Save all the gprs to the stack
  424.   move.l  a5,a1                  ;We need a5, so put MANX stack in a1
  425.   move.w  CountY(a5),i(a1)
  426.   move.l  BitMap(a1),a0
  427.   move.l  TL(a1),d0              ;Load Offset to Top,Left corner of screen
  428.   asl.l   #1,d0                  ; and make it a 'word' offset
  429.   move.l  Plane0(a0),a2          ;Get address of screens first bit plane
  430.   adda.l  d0,a2                  ; add in window top-left offset.
  431.   move.l  Plane1(a0),a3          ;Same for second bit plane.
  432.   adda.l  d0,a3
  433.   move.l  Plane2(a0),a4          ;Same for third bit plane.
  434.   adda.l  d0,a4
  435.   move.l  Plane3(a0),a5          ;Same for fourth bit plane.
  436.   adda.l  d0,a5
  437.   move.l  ColorPtr(a1),a0        ;Load up pointer to recolored data.
  438.   move.l  #1,d1                  ;/* for each row */
  439. ;                                ;for (i = CountY; i; i--) {
  440. Y2Loop4                            ; /* for each pixel in column */
  441.   move.w  Width(a1),d7           ;  for (k = Width; k; k--) {
  442.   eor.w   d2,d2                  ;  Clear all bits in the bit plane data regs.
  443.   eor.w   d3,d3
  444.   eor.w   d4,d4
  445.   eor.w   d5,d5
  446. B2Loop4
  447.   move.b  (a0)+,d0                ;   d0 = *(ColorPtr++);
  448.   asr.b   d1,d0                   ;   get low order bit from d0
  449.   addx.w  d2,d2                   ;   put it in bit plane 0 data
  450.   asr.b   d1,d0                   ;   same for bit plane 1
  451.   addx.w  d3,d3
  452.   asr.b   d1,d0                   ;   same for bit plane 2
  453.   addx.w  d4,d4
  454.   asr.b   d1,d0                   ;   same for bit plane 3
  455.   addx.w  d5,d5
  456.   sub.w   d1,d7                   ;   same for bit plane 5
  457.   bgt     B2Loop4                 ; } /* did each bit in bit plane word */
  458.   move.w  Mask(a1),d0             ; Turn off all the new bits in planes
  459.   and.w   d0,(a2)
  460.   and.w   d0,(a3)
  461.   and.w   d0,(a4)
  462.   and.w   d0,(a5)
  463.   move.w  #16,d0
  464.   sub.w   Width(a1),d0
  465.   asl.w   d0,d2
  466.   asl.w   d0,d3
  467.   asl.w   d0,d4
  468.   asl.w   d0,d5
  469.   or.w    d2,(a2)+                ; Set the new bits in the bit planes
  470.   or.w    d3,(a3)+
  471.   or.w    d4,(a4)+
  472.   or.w    d5,(a5)+
  473.   move.l  Mod(a1),d0              ; Adjust plane pointers to start of next line
  474.   add.l   d0,d0
  475.   add.l   d0,a2
  476.   add.l   d0,a3
  477.   add.l   d0,a4
  478.   add.l   d0,a5
  479.   adda.l  CMod(a1),a0             ; Adjust color pointer to start of next line
  480.   sub.w   d1,i(a1)               ;} /* did each row */
  481.   tst.w   i(a1)
  482.   bgt     Y2Loop4
  483.   movem.l (sp)+,SaveReg          ;better restore the registers
  484. #endasm
  485.   ;
  486.   }
  487. } /* ReColor 4 bit planes */
  488.  
  489.  
  490. /*
  491.  * Assembly code to recolor 5 bit planes
  492.  */
  493. ReColor5(ColorSave, Pict)
  494.   UBYTE *ColorSave;
  495.   register struct Picture *Pict;
  496. {
  497.   /* This set of variables should not be rearranged or moved.
  498.      There is Assembly language used in this routine, to increase
  499.      performance.  The assembly code depends on these variables
  500.      being located on Manx's stack.  Obviously it is not too portable
  501.      or maintainable, but it is faster.
  502.    */
  503.   SHORT  Mask,Width;
  504.   LONG   Mod,CMod;
  505.   SHORT  LF,LP,RF,RP;
  506.   SHORT  i,j,k,l;
  507.   LONG   Sx,TL;
  508.   UBYTE  *ColorPtr;
  509.  
  510.   struct BitMap *BitMap;
  511.  
  512.   /* These can be messed with */
  513.  
  514.   SHORT  CountX, CountY;
  515.  
  516.   register struct Window  *Window;
  517.  
  518.   Window = Pict->Window;
  519.   BitMap = Window->RPort->BitMap;
  520.  
  521.   CountX = Pict->CountX;
  522.   CountY = Pict->CurLine;
  523.  
  524.   ColorPtr = ColorSave;
  525.   Sx = (screen->Width + 15) >> 4;
  526.   LP = Window->LeftEdge + Pict->LeftMarg;
  527.   LF = (LP + 15) & 0xfff0;
  528.   CMod = CountX - (LF-LP);
  529.   Mod = Sx - 1;
  530.   TL = Sx *  (Window->TopEdge + Pict->TopMarg) + (LP-1 >> 4);
  531.   Width = LF-LP;
  532.   Mask = 0xffff << Width;
  533.  
  534.   if ( Width > 0 ) {
  535.  
  536. #asm
  537.   movem.l SaveReg,-(sp)          ;Save all the gprs to the stack
  538.   move.l  a5,a1                  ;We need a5, so put MANX stack in a1
  539.   move.w  CountY(a5),i(a1)
  540.   move.l  BitMap(a1),a0
  541.   move.l  TL(a1),d0              ;Load Offset to Top,Left corner of screen
  542.   asl.l   #1,d0                  ; and make it a 'word' offset
  543.   move.l  Plane0(a0),a2          ;Get address of screens first bit plane
  544.   adda.l  d0,a2                  ; add in window top-left offset.
  545.   move.l  Plane1(a0),a3          ;Same for second bit plane.
  546.   adda.l  d0,a3
  547.   move.l  Plane2(a0),a4          ;Same for third bit plane.
  548.   adda.l  d0,a4
  549.   move.l  Plane3(a0),a5          ;Same for fourth bit plane.
  550.   adda.l  d0,a5
  551.   move.l  Plane4(a0),a6          ;Same for fifth bit plane.
  552.   adda.l  d0,a6
  553.   move.l  ColorPtr(a1),a0        ;Load up pointer to recolored data.
  554.   move.l  #1,d1                  ;/* for each row */
  555. ;                                ;for (i = CountY; i; i--) {
  556. Y0Loop5                            ; /* for each pixel in column */
  557.   move.w  Width(a1),d7           ;  for (k = Width; k; k--) {
  558.   eor.w   d2,d2                  ;  Clear all bits in the bit plane data regs.
  559.   eor.w   d3,d3
  560.   eor.w   d4,d4
  561.   eor.w   d5,d5
  562.   eor.w   d6,d6
  563. B0Loop5
  564.   move.b  (a0)+,d0               ;    d0 = *(ColorPtr++);
  565.   asr.b   d1,d0                  ;    get low order bit from d0
  566.   addx.w  d2,d2                  ;    put it in bit plane 0 data
  567.   asr.b   d1,d0                  ;    same for bit plane 1
  568.   addx.w  d3,d3
  569.   asr.b   d1,d0                  ;    same for bit plane 2
  570.   addx.w  d4,d4
  571.   asr.b   d1,d0                  ;    same for bit plane 3
  572.   addx.w  d5,d5
  573.   asr.b   d1,d0                  ;    same for bit plane 4
  574.   addx.w  d6,d6
  575.   sub.w   d1,d7                  ;    same for bit plane 5
  576.   bgt     B0Loop5                ;  } /* did each bit in bit plane word */
  577.   move.w  Mask(a1),d0            ;  Turn off all the new bits in planes
  578.   and.w   d0,(a2)
  579.   and.w   d0,(a3)
  580.   and.w   d0,(a4)
  581.   and.w   d0,(a5)
  582.   and.w   d0,(a6)
  583.   or.w    d2,(a2)+               ;  Set the new bits in the bit planes
  584.   or.w    d3,(a3)+
  585.   or.w    d4,(a4)+
  586.   or.w    d5,(a5)+
  587.   or.w    d6,(a6)+
  588.   move.l  Mod(a1),d0             ;  Adjust plane pointers to start of next line
  589.   add.l   d0,d0
  590.   add.l   d0,a2
  591.   add.l   d0,a3
  592.   add.l   d0,a4
  593.   add.l   d0,a5
  594.   add.l   d0,a6
  595.   adda.l  CMod(a1),a0            ;  Adjust color pointer to start of next line
  596.   sub.w   d1,i(a1)               ;} /* did each row */
  597.   tst.w   i(a1)
  598.   bgt     Y0Loop5
  599.   movem.l (sp)+,SaveReg          ;better restore the registers
  600. #endasm
  601.   ;
  602.   }
  603.  
  604.   RP = LP + CountX & 0xfff0;
  605.   RF = RP - 16;
  606.   CMod = CountX - (RP-LF);
  607.   Mod = Sx - ((RP-LF) >> 4);
  608.   TL++;
  609.   Width = (RP-LF) >> 4;
  610.   ColorPtr = ColorSave + LF - LP;
  611.  
  612.   if ( Width > 0 ) {
  613.  
  614. #asm
  615.   movem.l SaveReg,-(sp)          ;Save all the gprs to the stack
  616.   move.l  a5,a1                  ;We need a5, so put MANX stack in a1
  617.   move.w  CountY(a5),i(a1)          ;i = CountY;
  618.   move.l  BitMap(a1),a0
  619.   move.l  TL(a1),d0              ;Load Offset to Top,Left corner of screen
  620.   asl.l   #1,d0                  ; and make it a 'word' offset
  621.   move.l  Plane0(a0),a2          ;Get address of screens first bit plane
  622.   adda.l  d0,a2                  ; add in window top-left offset.
  623.   move.l  Plane1(a0),a3          ;Same for second bit plane.
  624.   adda.l  d0,a3
  625.   move.l  Plane2(a0),a4          ;Same for third bit plane.
  626.   adda.l  d0,a4
  627.   move.l  Plane3(a0),a5          ;Same for fourth bit plane.
  628.   adda.l  d0,a5
  629.   move.l  Plane4(a0),a6          ;Same for fifth bit plane.
  630.   adda.l  d0,a6
  631.   move.l  ColorPtr(a1),a0        ;Load up pointer to recolored data.
  632.   move.l  #1,d1                  ;/* for each row */
  633. ;                                ;for (i = CountY; i; i--) {
  634. YLoop5                            ; /* for each column */
  635.   move.w  Width(a1),j(a1)        ;  for (j = Width; j; j--) {
  636. XLoop5                               ; /* pack a word for each bit plane */
  637.   move.w  #16,d7                 ;    for (k = 16; k; k--) {
  638. BLoop5
  639.   move.b  (a0)+,d0               ;      d0 = *(ColorPtr++);
  640.   asr.b   d1,d0                  ;      get low order bit from d0
  641.   addx.w  d2,d2                  ;      put it in bit plane 0 data
  642.   asr.b   d1,d0                  ;      same for bit plane 1
  643.   addx.w  d3,d3
  644.   asr.b   d1,d0                  ;      same for bit plane 2
  645.   addx.w  d4,d4
  646.   asr.b   d1,d0                  ;      same for bit plane 3
  647.   addx.w  d5,d5
  648.   asr.b   d1,d0                  ;      same for bit plane 4
  649.   addx.w  d6,d6
  650.   sub.w   d1,d7                  ;      same for bit plane 5
  651.   bgt     BLoop5                 ;    } /* did each bit in bit plane word */
  652.   move.w  d2,(a2)+               ;    Save the packed data in bit planes
  653.   move.w  d3,(a3)+
  654.   move.w  d4,(a4)+
  655.   move.w  d5,(a5)+
  656.   move.w  d6,(a6)+
  657.   sub.w   d1,j(a1)               ;  } /* did each word in a row */
  658.   tst.w   j(a1)
  659.   bgt     XLoop5
  660.   move.l  Mod(a1),d0             ;  Adjust plane pointers to start of next line
  661.   add.l   d0,d0
  662.   add.l   d0,a2
  663.   add.l   d0,a3
  664.   add.l   d0,a4
  665.   add.l   d0,a5
  666.   add.l   d0,a6
  667.   adda.l  CMod(a1),a0            ;  Adjust color pointer to start of next line
  668.   sub.w   d1,i(a1)               ;} /* did each row */
  669.   tst.w   i(a1)
  670.   bgt     YLoop5
  671.   movem.l (sp)+,SaveReg          ;better restore the registers
  672. #endasm
  673.   ;
  674.   }
  675.  
  676.   TL += Width;
  677.   Width = LP + CountX - RP;
  678.   CMod = CountX - Width;
  679.   Mod = Sx - 1;
  680.   Mask = 0xffff >> Width;
  681.   ColorPtr = ColorSave + RP - LP;
  682.  
  683.   if ( Width > 0 ) {
  684. #asm
  685.   movem.l SaveReg,-(sp)          ;Save all the gprs to the stack
  686.   move.l  a5,a1                  ;We need a5, so put MANX stack in a1
  687.   move.w  CountY(a5),i(a1)
  688.   move.l  BitMap(a1),a0
  689.   move.l  TL(a1),d0              ;Load Offset to Top,Left corner of screen
  690.   asl.l   #1,d0                  ; and make it a 'word' offset
  691.   move.l  Plane0(a0),a2          ;Get address of screens first bit plane
  692.   adda.l  d0,a2                  ; add in window top-left offset.
  693.   move.l  Plane1(a0),a3          ;Same for second bit plane.
  694.   adda.l  d0,a3
  695.   move.l  Plane2(a0),a4          ;Same for third bit plane.
  696.   adda.l  d0,a4
  697.   move.l  Plane3(a0),a5          ;Same for fourth bit plane.
  698.   adda.l  d0,a5
  699.   move.l  Plane4(a0),a6          ;Same for fifth bit plane.
  700.   adda.l  d0,a6
  701.   move.l  ColorPtr(a1),a0        ;Load up pointer to recolored data.
  702.   move.l  #1,d1                  ;/* for each row */
  703. ;                                ;for (i = CountY; i; i--) {
  704. Y2Loop5                          ;  ; /* for each pixel in column */
  705.   move.w  Width(a1),d7           ;  for (k = Width; k; k--) {
  706.   eor.w   d2,d2                  ;  Clear all bits in the bit plane data regs.
  707.   eor.w   d3,d3
  708.   eor.w   d4,d4
  709.   eor.w   d5,d5
  710.   eor.w   d6,d6
  711. B2Loop5
  712.   move.b  (a0)+,d0               ;    d0 = *(ColorPtr++);
  713.   asr.b   d1,d0                  ;    get low order bit from d0
  714.   addx.w  d2,d2                  ;    put it in bit plane 0 data
  715.   asr.b   d1,d0                  ;    same for bit plane 1
  716.   addx.w  d3,d3
  717.   asr.b   d1,d0                  ;    same for bit plane 2
  718.   addx.w  d4,d4
  719.   asr.b   d1,d0                  ;    same for bit plane 3
  720.   addx.w  d5,d5
  721.   asr.b   d1,d0                  ;    same for bit plane 4
  722.   addx.w  d6,d6
  723.   sub.w   d1,d7                  ;    same for bit plane 5
  724.   bgt     B2Loop5                ;  } /* did each bit in bit plane word */
  725.   move.w  Mask(a1),d0            ;  Turn off all the new bits in planes
  726.   and.w   d0,(a2)
  727.   and.w   d0,(a3)
  728.   and.w   d0,(a4)
  729.   and.w   d0,(a5)
  730.   and.w   d0,(a6)
  731.   move.w  #16,d0
  732.   sub.w   Width(a1),d0
  733.   asl.w   d0,d2
  734.   asl.w   d0,d3
  735.   asl.w   d0,d4
  736.   asl.w   d0,d5
  737.   asl.w   d0,d6
  738.   or.w    d2,(a2)+               ;  Set the new bits in the bit planes
  739.   or.w    d3,(a3)+
  740.   or.w    d4,(a4)+
  741.   or.w    d5,(a5)+
  742.   or.w    d6,(a6)+
  743.   move.l  Mod(a1),d0             ;  Adjust plane pointers to start of next line
  744.   add.l   d0,d0
  745.   add.l   d0,a2
  746.   add.l   d0,a3
  747.   add.l   d0,a4
  748.   add.l   d0,a5
  749.   add.l   d0,a6
  750.   adda.l  CMod(a1),a0            ;  Adjust color pointer to start of next line
  751.   sub.w   d1,i(a1)               ;} /* did each row */
  752.   tst.w   i(a1)
  753.   bgt     Y2Loop5
  754.   movem.l (sp)+,SaveReg          ;better restore the registers
  755. #endasm
  756.   ;
  757.   }
  758.  
  759. } /* ReColor 5 bit planes */
  760.  
  761. static struct Picture *ReColorPict;
  762.  
  763. ReColorSlow( Pict )
  764.   register struct Picture *Pict;
  765. {
  766.   int ReColorTask();
  767.  
  768.   WindowToFront(Pict->Window);
  769.  
  770.   Pict->ColorState = GENERATESTATE;
  771.  
  772.   ReColorPict = Pict;
  773.  
  774.   Pict->cTask = CreateTask( "ReColor", 0, ReColorTask, 1024);
  775.  
  776.   if ( Pict->cTask == NULL ) {
  777.     DispErrMsg("Could not create recolor task",0);
  778.   }
  779.  
  780.   /* Do this so we are sure child is done with ReColorPict */
  781.  
  782.   Wait( pSigMask );
  783. }
  784.  
  785. ReColorTask( )
  786. {
  787.   register struct Picture  *Pict;
  788.   register struct RastPort *Rp;
  789.   register UBYTE  OldColor, NewColor;
  790.  
  791.   register LONG   x, y;
  792.            LONG   xl, yl;
  793.  
  794.   SHORT *CountPtr;
  795.  
  796.   struct Window *Window;
  797.  
  798.   geta4();
  799.  
  800.   Pict = ReColorPict;
  801.  
  802.   /* Signal Parent that we have accessed ReColorPict */
  803.  
  804.   Signal( mTask, pSigMask );
  805.  
  806.   Window = Pict->Window;
  807.   Pict->ColorChildState = RECOLORINCOMPLETE;
  808.  
  809.   Rp = Window->RPort;
  810.   CountPtr = Pict->Counts;
  811.  
  812.   OldColor = 0xff;
  813.  
  814.   xl = Pict->CountX  + Pict->LeftMarg;
  815.   yl = Pict->CurLine + Pict->TopMarg;
  816.  
  817.   for (y = Pict->TopMarg; y < yl; y++) {
  818.  
  819.     ObtainSemaphore( &Pict->WindowSemi );
  820.  
  821.     OldColor = *(Pict->ClrXlate + *CountPtr);
  822.     Move( Rp, Pict->LeftMarg, y);
  823.  
  824.     for (x = Pict->LeftMarg; x < xl; x++) {
  825.  
  826.       NewColor = *(Pict->ClrXlate + *CountPtr++);
  827.  
  828.       if ( NewColor != OldColor) {
  829.  
  830.         SetAPen( Rp, OldColor );
  831.  
  832.         if ( x < Window->Width - Window->BorderRight) {
  833.           Draw( Rp, x, y);
  834.         }
  835.  
  836.         OldColor = NewColor;
  837.       }
  838.     }
  839.     SetAPen( Rp, NewColor );
  840.     Draw( Rp, x-1, y);
  841.  
  842.     ReleaseSemaphore( &Pict->WindowSemi );
  843.  
  844.     ReColorPause( Pict );
  845.   }
  846.   Pict->ColorChildState = RECOLORCOMPLETE;
  847.  
  848.   /* Indicate that generation has finished for this task */
  849.  
  850.   Signal( mTask, mSigMask );               /* signal parent as to change */
  851.  
  852.   while (Pict->ColorState != PAUSESTATE) ;
  853.  
  854.   ReColorPause(Pict);  /* signal back so parent doesn't hang */
  855. } /* ReColorTask */
  856.  
  857. KillReColor( Pict )
  858.   register struct Picture *Pict;
  859. {
  860.   register struct Task *cTask;
  861.  
  862.   if ( cTask = Pict->cTask ) {
  863.  
  864.     PauseReColor( Pict );
  865.     DeleteTask( cTask );
  866.     Pict->cTask = NULL;
  867.   }
  868. }
  869.  
  870.